﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Collections.Generic;
using System.Linq;
using Microsoft.Phone.Controls;
using System.IO;


using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using Qplus.protocol;
using Qplus.Commands;
using Qplus.enums;


namespace Qplus.Infrastructure
{
    public class TcpSocket
    {
        private Socket socketConnection;

        private string server;
        private int serverPort;
        private const int bufferSize = 65535;

        public event EventHandler<CreateConnectionAsyncArgs> CreateConnectionCompleted;
        public event EventHandler<MessageReceivedFromServer> MessageReceivedFromServer;

        /**
	     * 创建一个socket代理，不关联socket
	     */
        public TcpSocket()
        {
            this.socketConnection = null;
        }

        /**
	     * 创建一个socket代理并关联socket
	     * @param mysocket
	     */
        TcpSocket(Socket mysocket)
        {
            this.socketConnection = mysocket;
        }

        /**
	     * 创建一个socket代理并关联socket
	     * @param sock
	     */
        public TcpSocket(string ipaddr, int port)
        {
            this.socketConnection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.server = ipaddr;
            this.serverPort = port;
        }

        //get a tcp socket connection
        public Socket tcpSocketConnection
        {
            get { return this.socketConnection; }
        }

        public void CreateConnection(string ipaddr, int port)
        {
		    this.socketConnection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.server = ipaddr;
            this.serverPort = port;
		    try {
                var connectionOperation = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(ipaddr, port) };
                this.socketConnection.ConnectAsync(connectionOperation);
                connectionOperation.Completed += OnConnectionToServerCompleted;
            }
            catch (SocketException se)
            {
                Debug.WriteLine(se.Message);
		    }
		
	    }

        private void OnConnectionToServerCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success)
            {
                if (CreateConnectionCompleted != null)
                    CreateConnectionCompleted(this, new CreateConnectionAsyncArgs(false));

                return;
            }

            if (CreateConnectionCompleted != null)
                CreateConnectionCompleted(this, new CreateConnectionAsyncArgs(true));

            ReceiveMessage();
        }

        /**
	     * 
	     * 关闭 System.Net.Sockets.Socket 连接并释放与指定超时关联的所有资源，以允许发送排队的数据。
	     */
        public void close(int timeout)
        {
            this.socketConnection.Close(timeout);
	    }


        public void SendToServer(byte[] buffer)
        {
            Debug.WriteLine("Send message to server");

            var asyncEvent = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(server, serverPort) };

            asyncEvent.SetBuffer(buffer, 0, buffer.Length);

            socketConnection.SendAsync(asyncEvent);
        }


        public void ReceiveMessage()
        {
            var responseListener = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(server, serverPort) };
            responseListener.Completed += OnMessageReceivedFromServer;

            var responseBuffer = new byte[bufferSize];
            responseListener.SetBuffer(responseBuffer, 0, bufferSize);

            socketConnection.ReceiveAsync(responseListener);
        }

        private void OnMessageReceivedFromServer(object sender, SocketAsyncEventArgs e)
        {

            if (e.SocketError == SocketError.Success)
            {
                //get the received message
                byte[] receivedMessage = new byte[e.BytesTransferred];

                Array.Copy(e.Buffer, 0, receivedMessage, 0, e.BytesTransferred);

                ProcessIncomingMessage(receivedMessage);

            }
            Debug.WriteLine(e.SocketError);
            var message = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);

            Debug.WriteLine(message);
            Debug.WriteLine("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

            int msgID=e.Buffer[3]+e.Buffer[4]*256;
            switch ((MMessageID)msgID)
            {
                case MMessageID.L2C_RESP_LOGIN:
                    {
                        UI.UIData uidata = UI.UIData.getInstance();
                        uidata.L2C = new UI.l2cInfo(e.Buffer, e.BytesTransferred);
                        //MainPage currentpage = MainPage.getInstance();
                        //currentpage.NavigationService.Navigate(new Uri("/UI/EntryPage.xaml", UriKind.Relative));
                        break;
                    }
                default:
                    break;
            }
            
            //uidata.GetUserList(0);
            //uidata.GetRoomList(0);
            #region L2C_RESP_LOGIN
            //Dictionary<string, object> param = new Dictionary<string, object>();
            //Dictionary<string, string> dict = new Dictionary<string, string>();
            //L2C_RESP_LOGIN l2c = new L2C_RESP_LOGIN();
            ////l2c.setData(e.Buffer);
            //l2c.handle(e.Buffer, 0, e.BytesTransferred);

            /////**
            //// * * 验证结果
            //// * */
            //int result = l2c.getResult();
            /////**
            ////* 用户服务器ip
            ////*/
            //string ip = l2c.getIP();

            //Debug.WriteLine(ip);

            /////**
            ////* 用户服务器端口
            ////*/
            //int port = l2c.getPort();

            /////**
            ////* 用户id
            ////*/
            //long userID = l2c.getUserID();

            /////**
            ////* 密钥
            ////*/
            //byte[] key = l2c.getKey();
            /////**
            //// * 升级服务器地址
            //// */
            //string upgradeURL = l2c.getUpgradeURL();

            //Debug.WriteLine(upgradeURL);

            //Qplus.UI.UIData uidata = Qplus.UI.UIData.getInstance();
            //uidata.L2C = new Qplus.UI.l2cInfo() { Result = result, Ip = ip, Port = port, UserID = userID, Key = key, UpgradeURL = upgradeURL };
            //Qplus.UI.l2cInfo newInfo = new Qplus.UI.l2cInfo() { Result =result,Ip =ip,Port=port,UserID=userID,Key=key,UpgradeURL=upgradeURL};
            //Qplus.UI.l2cInfo local;
            //System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.TryGetValue<Qplus.UI.l2cInfo>("l2cInfo", out local);
            //if (null == local)
            //{
            //    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.Add("l2cInfo", newInfo);//["userList"] = userList;
            //    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.TryGetValue<Qplus.UI.l2cInfo>("l2cInfo", out local);
            //    if (null == local) return;
            //}
            
            ////GetChatListCommand command_GetChatList = new GetChatListCommand(local.UserID.ToString(), System.Text.Encoding.UTF8.GetString(local.Key,0,local.Key.Length));
            ////command_GetChatList.execute(local.UpgradeURL);
            //GetUserListCommand command_GetUserList = new GetUserListCommand(userID, key);
            //command_GetUserList.set(0);
            //command_GetUserList.execute(upgradeURL);

            //GetRoomListCommand command_GetRoomList = new GetRoomListCommand(local.UserID.ToString(), System.Text.Encoding.UTF8.GetString( local.Key,0,local.Key.Length));
            //command_GetRoomList.set(0);
            //command_GetRoomList.execute(local.UpgradeURL);
            #endregion
        }
        private void ProcessIncomingMessage(byte[] ReceivedMessage)
        {
            // Future hook for handling the message in somewhere else.
            // It's most probably wise to put the parsing logic in some other class.
            if (MessageReceivedFromServer != null)
                MessageReceivedFromServer(this, new MessageReceivedFromServer(ReceivedMessage));
        }

        void proxy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            //Process the result... 
            string data = e.Result;

            Debug.WriteLine(data);
        }
    }
    }
}
